﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Linq;
using System.Text;


public class Hero : ViewableObject
{
    
    public Dictionary<String, Animation> animations;
    public int directionVar = 1;
    private String runAnimName = "run";
    private String idleAnimName = "idle";
    private String jumpAnimName = "jump";
    private String deadAnimName = "dead";
    private String deadFlatAnimName = "deadFlat";
    private String holdingIdleAnimName = "holdingIdle";
    private String holdingJumpAnimName = "holdingJump";
    private String holdingRunAnimName = "holdingRun";
    private int RUN_SPEED = 2;
//    private int directionVal = 1;
    private Boolean isRunning = false;
    private Boolean isIdle = true;
    private SpriteEffects effects;

    public Hero()
        : base(ViewableObject.Type.Hero, new Vector3(0,0,0))
    {
        init();
    }

    public Hero(ViewableObject.Type type, Vector3 placement)
        : base(type, placement)
    {
        init();
    }

    private void init()
    {
        animations = new Dictionary<String, Animation>();
        propagateAnimations();
        currentAnimation = animations[runAnimName];
    }

    /**
     * This method creates all the animations used by the hero. It creates an animation object and adds the appropriate
     * frames to the animations using specific assets from the AssetLibrary.
     */
    public void propagateAnimations()
    {
        

        Animation runAnimation = new Animation(runAnimName, 12, true);
        Animation idleAnimation = new Animation(idleAnimName, 12, false);
        Animation jumpAnimation = new Animation(jumpAnimName, 12, false);
        Animation deadAnimation = new Animation(deadAnimName, 12, false);
        Animation deadFlatAnimation = new Animation(deadFlatAnimName, 12, false);
        Animation holdingIdleAnimation = new Animation(holdingIdleAnimName, 12, false);
        Animation holdingJumpAnimation = new Animation(holdingJumpAnimName, 12, false);
        Animation holdingRunAnimation = new Animation(holdingRunAnimName, 12, false);
        
        
        int i;

        // hero run animation.
        for ( i = 0; i < 4; i++ )
        {

            runAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroRunTest"),
                        new Rectangle(i * 116, 0, 116, 179),
                        0,
                        new Vector2(60, 179)));

        }

        for (i = 0; i < 4; i++)
        {

            runAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroRunTest"),
                        new Rectangle(i * 116, 179, 116, 179),
                        0,
                        new Vector2(60, 179)));

        }
        
        // hero idle animation
        idleAnimation.addFrame(
            new Frame(
                Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroIdleTest"),
                new Rectangle(0, 0, 116, 179), 
                0,
                new Vector2(60, 179)));
        

        // hero jump animation
        for (i = 0; i < 4; i++)
        {

            jumpAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroJump"),
                        new Rectangle(i * 116, 0, 116, 179),
                        0,
                        new Vector2(60, 179)));

        }

        for (i = 0; i < 3; i++)
        {

            jumpAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroJump"),
                        new Rectangle(i * 116, 179, 116, 179),
                        0,
                        new Vector2(60, 179)));

        }
        jumpAnimation.setLoopable(false);

        // hero dead animation
        deadAnimation.addFrame(
            new Frame(
                Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroDead"),
                new Rectangle(0, 0, 116, 179),
                0,
                new Vector2(60, 179)));
        
        // hero dead flat animation
        deadFlatAnimation.addFrame(
            new Frame(
                Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroDeadFlat"),
                new Rectangle(0, 0, 185, 43),
                0,
                new Vector2(92, 43)));

        // hero holding idle animation
        holdingIdleAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroHoldingIdle"),
                        new Rectangle(0, 0, 106, 160),
                        0,
                        new Vector2(53, 160)));
        
        // hero holding jump animation
        for (i = 0; i < 4; i++)
        {

            holdingJumpAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroHoldingJump"),
                        new Rectangle(i * 109, 0, 109, 170),
                        0,
                        new Vector2(54, 170)));

        }

        for (i = 0; i < 3; i++)
        {

            holdingJumpAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroHoldingJump"),
                        new Rectangle(i * 109, 170, 109, 170),
                        0,
                        new Vector2(54, 170)));

        }

        // hero holding run animation
        for (i = 0; i < 4; i++)
        {

            holdingRunAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroHoldingRun"),
                        new Rectangle(i * 120, 0, 120, 179),
                        0,
                        new Vector2(60, 179)));

        }

        for (i = 0; i < 4; i++)
        {

            holdingRunAnimation.addFrame(
                    new Frame(
                        Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.HERO).get("heroHoldingRun"),
                        new Rectangle(i * 120, 179, 120, 179),
                        0,
                        new Vector2(60, 179)));

        }


        animations.Add("idle", idleAnimation);
        animations.Add("run", runAnimation);
        animations.Add("jump", jumpAnimation);
        animations.Add("dead", deadAnimation);
        animations.Add("deadFlat", deadFlatAnimation);
        animations.Add("holdingIdle", holdingIdleAnimation);
        animations.Add("holdingJump", holdingJumpAnimation);
        animations.Add("holdingRun", holdingRunAnimation);
    }

    public override void update(Double timeElapsed)
    {
        base.update(timeElapsed);
        updateLogic();
        currentAnimation.update(timeElapsed);
        currentAnimation.setEffects(effects);
    }

    public void updateLogic()
    {
        isRunning = false;

        if (InputManager.getSingleton().getControlState(InputManager.LEFT_BUTTON) || InputManager.LEFT_ANALOG_LEFT)
        {
            move(-RUN_SPEED, 0, 0);
            isRunning = true;
            effects = SpriteEffects.FlipHorizontally;
        }
        else if (InputManager.getSingleton().getControlState(InputManager.RIGHT_BUTTON) || InputManager.LEFT_ANALOG_RIGHT)
        {
            move(RUN_SPEED, 0, 0);
            isRunning = true;
            effects = SpriteEffects.None;

        }
        if (InputManager.getSingleton().getControlState(InputManager.UP_BUTTON) || InputManager.LEFT_ANALOG_UP)
        {
            move(0, 0, RUN_SPEED*2);
            isRunning = true;

        }
        else if (InputManager.getSingleton().getControlState(InputManager.DOWN_BUTTON) || InputManager.LEFT_ANALOG_DOWN)
        {
            move(0, 0, -RUN_SPEED*2);
            isRunning = true;

        }

        setAnimations();
    }

    public void move(int x, int y, int z)
    {
        updateCollisionBoxes(x, y, z);
        origin.X += x;
        origin.Y += y;
        origin.Z += z;
    }

    public void updateCollisionBoxes(int x, int y, int z)
    {
        min.X += x;
        min.Y += y;
        min.Z += z;

        max.X += x;
        max.Y += y;
        max.Z += z;
    }

    private void setAnimations(){
        if(isRunning){
            currentAnimation = animations[runAnimName];
        }
        else if (isIdle)
        {
            currentAnimation = animations[idleAnimName];
        }
    }
}

